# Install pacman if needed
if (!require("pacman")) install.packages("pacman")
# Install all required packages
pacman::p_load(
tidyverse, # Data manipulation and visualization
sf, # Simple features for spatial data
blosc, # to handled compression of large data
rnaturalearth, # World map data
rnaturalearthdata,
CopernicusMarine # Access Copernicus data
)Visualizing Ocean Currents with Copernicus Marine Data & R
A Tutorial on Downloading and Mapping the Gulf Stream
Introduction
This tutorial demonstrates how to download ocean current data from the Copernicus Marine Service and create beautiful visualizations of the Gulf Stream. We’ll learn to:
- Access Copernicus Marine data using the
CopernicusMarineR package. - Process ocean current vectors (u and v components)
- Calculate current speed.
- Create multi-panel maps showing temporal changes
Setup
Install Required Packages
Load Libraries
pacman::p_load(
tidyverse, # Data manipulation and visualization
sf, # Simple features for spatial data
blosc, # to handled compression of large data
rnaturalearth, # World map data
rnaturalearthdata,
CopernicusMarine # Access Copernicus data
)Understanding the Data
Copernicus Marine Service
The Global Ocean Physics Analysis and Forecast provides:
- Product ID:
GLOBAL_ANALYSISFORECAST_PHY_001_024 - Dataset
cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m - Spatial Resolution: 0.083° (~9 km)
- Variables: Ocean currents (u, v components), temperature, salinity, etc.
- Temporal Coverage: Daily forecasts and historical data
Ocean Current Components
Ocean currents are described by two velocity components:
- uo: Eastward velocity (u component) in m/s
- vo: Northward velocity (v component) in m/s
The total speed is calculated as: \(\text{speed} = \sqrt{u^2 + v^2}\)
Data Download
Define Parameters
# Product information
product_id <- "GLOBAL_ANALYSISFORECAST_PHY_001_024"
dataset_id <- "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m"
# Variables to download
vars <- c("uo", "vo") # Current components
# Spatial extent (Gulf Stream region)
region <- c(-85, 20, -33, 68) # lon_min, lat_min, lon_max, lat_max
# Depth level (surface)
depth_level <- c(0, -0.5)
# Time periods (monthly snapshots)
times <- seq.Date(
ymd('2023-09-01'),
ymd('2023-12-01'),
by = 'month'
)Download Data
This loop downloads data for each time period:
current_list <- lapply(times, function(tiempo) {
# Download subset from Copernicus
currents <- cms_download_subset(
destination = "file.nc",
product = product_id,
layer = dataset_id,
variable = vars,
region = region,
timerange = c(tiempo, tiempo),
verticalrange = depth_level
)
# Convert to dataframe
curr_df <- currents %>%
st_as_sf() %>% # from stars to sf
mutate(across(where(~ inherits(.x, "units")), as.numeric)) %>%
mutate(
lon = st_coordinates(st_centroid(.))[,1],
lat = st_coordinates(st_centroid(.))[,2],
speed = sqrt(uo^2 + vo^2), # Calculate speed
time_step = tiempo
) %>%
st_drop_geometry()
return(curr_df)
})
# Combine all time periods
curr_df <- bind_rows(current_list)
NoteDownload Time
Downloading data can take several minutes depending on your internet connection, amount of data and the Copernicus server load.
Data Exploration
Let’s examine the structure of our data:
# View data structure
glimpse(curr_df)Rows: 1,064,656
Columns: 6
$ uo <dbl> -0.08716235, -0.12335874, -0.14933379, -0.15880683, -0.15646…
$ vo <dbl> -0.06952941, -0.09073421, -0.11591692, -0.14538065, -0.16659…
$ lon <dbl> -84.95833, -84.87499, -84.79166, -84.70833, -84.62499, -84.5…
$ lat <dbl> 20.08333, 20.08333, 20.08333, 20.08333, 20.08333, 20.08333, …
$ speed <dbl> 0.1114971, 0.1531342, 0.1890431, 0.2153024, 0.2285487, 0.232…
$ time_step <date> 2023-09-01, 2023-09-01, 2023-09-01, 2023-09-01, 2023-09-01,…
# Summary statistics
summary(curr_df$speed) Min. 1st Qu. Median Mean 3rd Qu. Max.
0.0001411 0.0891034 0.1520449 0.2131764 0.2610403 2.5532521
# Check time periods
unique(curr_df$time_step)[1] "2023-09-01" "2023-10-01" "2023-11-01" "2023-12-01"
Expected columns:
lon,lat: Geographic coordinatesuo,vo: Current velocity components (m/s)speed: Calculated current speed (m/s)time_step: Date of observation
Visualization
Prepare Map Components
# Sample data for arrow visualization (optional)
curr_sample <- curr_df %>%
sample_frac(0.005) # Use 0.5% of points to avoid overcrowding
# Load world coastline
world <- ne_countries(scale = "small", returnclass = "sf")Create the Map
g <- ggplot() +
# Raster layer showing current speed
geom_raster(
data = curr_df,
aes(x = lon, y = lat, fill = speed)
) +
# Coastline overlay
geom_sf(
data = world,
fill = 'black',
color = "white",
linewidth = 0.5
) +
# Optional: Add current direction arrows
# geom_segment(
# data = curr_sample,
# aes(x = lon, y = lat,
# xend = lon + uo*10,
# yend = lat + vo*10),
# arrow = arrow(length = unit(0.15, "cm")),
# linewidth = 0.5,
# color = "black"
# ) +
# Color scale
scale_fill_viridis_c(
name = "Speed (m/s)",
option = "turbo"
) +
# Set map bounds
coord_sf(
xlim = c(-85, -33),
ylim = c(20, 68),
expand = FALSE
) +
# Create panels for each time period
facet_wrap(~time_step, nrow = 1) +
# Labels
labs(
title = "Gulf Stream Current Speed",
subtitle = "September - December 2023",
caption = "Data: Global Ocean Physics Analysis and Forecast, Copernicus Marine Service",
x = "Longitude",
y = "Latitude"
) +
# Theme
theme(
legend.position = 'bottom',
legend.title.position = 'top',
legend.key.width = unit(2, "cm"),
text = element_text(colour = 'white', size = 15),
axis.text = element_text(colour = 'white', size = 12),
plot.background = element_rect(fill = "black"),
legend.background = element_rect(fill = 'black')
)
# Display
gSave the Plot
ggsave(
g,
filename = 'Gulf_Stream.png',
width = 15,
height = 8,
units = 'in',
dpi = 300
)Interpretation
Understanding the Gulf Stream
The Gulf Stream is a powerful, warm ocean current in the North Atlantic that:
- Originates in the Gulf of Mexico
- Flows along the US East Coast
- Affects weather patterns in North America and Europe
- Shows seasonal and inter-annual variability
What to Look For
In the visualization, observe:
- Speed patterns: The core of the Gulf Stream (red/yellow) vs. slower surrounding waters
- Temporal changes: Monthly variations in position and intensity
- Eddies: Circular features that spin off from the main current
- Meandering: The Gulf Stream path is not straight but waves and curves